﻿// This file is part of Code4Public (http://code4public.codeplex.com)
// Copyright 2011 Sina Iravanian - <sina@sinairv.com>
//
// This source file(s) may be redistributed, altered and customized
// by any means PROVIDING the authors name and all copyright
// notices remain intact.
// THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED. USE IT AT YOUR OWN RISK. THE AUTHOR ACCEPTS NO
// LIABILITY FOR ANY DATA DAMAGE/LOSS THAT THIS PRODUCT MAY CAUSE.
// ------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Diagnostics;
using YAXLib;

namespace Code4Public.Languages
{
    [YAXSerializeAs("root")]
    public class Languages : List<LanguageInfo>
    {
        public Languages()
        {
        }

        public Languages(string path)
        {
            if (String.IsNullOrEmpty(path))
                throw new ArgumentException("path cannot be empty or null!", "path");

            if (!File.Exists(path))
                throw new FileNotFoundException("The specified file cannot be found!", path);

            var ser = new YAXSerializer(typeof(Languages), YAXExceptionHandlingPolicies.ThrowErrorsOnly, YAXExceptionTypes.Warning);
            var col = (Languages)ser.DeserializeFromFile(path);
            Debug.Assert(col != null);
            AddRange(col);
            ParsingErrors = ser.ParsingErrors;
        }

        public void SaveToFile(string path)
        {
            if (String.IsNullOrEmpty(path))
                throw new ArgumentException("Path cannot be empty or null!", "path");

            var ser = new YAXSerializer(typeof(Languages), YAXExceptionHandlingPolicies.ThrowErrorsOnly, YAXExceptionTypes.Warning);
            ser.SerializeToFile(this, path);
        }

        /// <summary>
        /// Gets a reference to the selected language. <c>null</c> if no language is selected.
        /// To select a language one must call the <code>SelectLanguage</code> method.
        /// </summary>
        public LanguageInfo SelectedLanguage { get; private set; }

        /// <summary>
        /// Gets a reference to the collection of parsing errors.
        /// </summary>
        public YAXParsingErrors ParsingErrors { get; private set; }

        /// <summary>
        /// Gets if there were any errors during parsing the languages config file.
        /// </summary>
        public bool HasErrors
        {
            get
            {
                return ParsingErrors != null && ParsingErrors.Count > 0;
            }
        }

        /// <summary>
        /// Gets an array of language names, retrieved from the languages config file.
        /// </summary>
        public IEnumerable<string> LanguageNames
        {
            get
            {
                return from lang in this select lang.LanguageName;
            }
        }

        /// <summary>
        /// Checks whether any language is selected.
        /// To select a language one must call the <code>SelectLanguage</code> method.
        /// </summary>
        public bool IsAnyLanguageSelected
        {
            get { return SelectedLanguage != null; }
        }

        /// <summary>
        /// Gets the name of the selected language. returns null if no languages are selected.
        /// </summary>
        public string SelectedLanguageName
        {
            get 
            {
                return IsAnyLanguageSelected ? SelectedLanguage.LanguageName : null;
            }

            set
            {
                var foundLang = this.FirstOrDefault(lang => lang.LanguageName == value);
                SelectedLanguage = foundLang;
                if (foundLang == null)
                    throw new ArgumentException("No language with this name is found: " + value, "value");
            }
        }

        /// <summary>
        /// Selects no languages. It sets the reference to the selected language to null.
        /// </summary>
        public void SelectNoLanguage()
        {
            SelectedLanguage = null;
        }
    }
}
